home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
414_01
/
execute.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-29
|
75KB
|
2,109 lines
/***********************************************************************/
/* EXECUTE.C - */
/* This file contains all functions that actually execute one or other */
/* commands. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1993 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Header: C:\THE\RCS\execute.c 1.4 1993/09/01 16:26:20 MH Interim MH $
*/
#include <stdio.h>
#include "the.h"
#include "proto.h"
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern WINDOW *foot,*error_window;
extern bool error_on_screen;
extern char *rec;
extern unsigned short rec_len;
extern char in_profile; /* indicates if processing profile */
extern char *temp_cmd;
/***********************************************************************/
#ifdef PROTO
int execute_change_command(char *params,bool selective)
#else
int execute_change_command(params,selective)
char *params;
bool selective;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
#define ALT_PARAMS 4
char *word[ALT_PARAMS];
char parm[ALT_PARAMS];
register int i;
unsigned short num_params;
long num_lines,long_n,long_m;
unsigned short x,y;
LINE *curr;
char old_str[60],new_str[60],target[60],n[20],m[20];
short rc,selective_rc=RC_OK;
int direction;
short number_lines,number_changes,number_of_changes,number_of_occ;
short start_col,real_start,real_end,loc;
long true_line,last_true_line,final_target;
int len_old_str,len_new_str;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_change_command");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. Up to 4 parameters */
/* may be supplied. The first is the string to change and its new */
/* value, the second is the target, the third is the number of times */
/* to change the value on one line and lastly is which occurrence to */
/* change first. */
/*---------------------------------------------------------------------*/
rc = split_change_params(params,old_str,new_str,target,n,m);
if (rc == (-1))
{
display_error(36,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_NO_LINES_CHANGED);
}
/*---------------------------------------------------------------------*/
/* Check for any hex strings in both old_str and new_str. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->hex == ON)
{
if ((len_old_str = convert_hex_strings(old_str)) == (-1))
{
display_error(32,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if ((len_new_str = convert_hex_strings(new_str)) == (-1))
{
display_error(32,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
}
else
{
len_old_str = strlen(old_str);
len_new_str = strlen(new_str);
}
if ((num_lines = valid_target(target,get_true_line())) == TARGET_ERROR
|| CURRENT_FILE->number_lines == 0L)
{
display_error(17,target);
#ifdef TRACE
trace_return();
#endif
return(RC_TARGET_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* If the number of lines is zero, don't make an y changes. Exit with */
/* no rows changed. */
/*---------------------------------------------------------------------*/
if (num_lines == 0L)
{
display_error(36,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_NO_LINES_CHANGED);
}
if (strcmp(n,"*") == 0)
long_n = MAX_LONG;
else
if (!valid_positive_integer(n))
{
display_error(4,n);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
else
long_n = atol(n);
if (!valid_positive_integer(m))
{
display_error(4,m);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
else
long_m = atol(m);
direction = (num_lines < 0) ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
/*---------------------------------------------------------------------*/
/* Determine where to start changing. */
/* If target is ALL, start with first line... */
/* If on command line or in profile, use current_line... */
/* Else, use focus line. */
/*---------------------------------------------------------------------*/
if (equal((char *)"all",target,3))
true_line = 1L;
else
true_line = get_true_line();
final_target = true_line+num_lines;
/*---------------------------------------------------------------------*/
/* If the true_line is on the top or bottom of file lines and we are */
/* searching forward or backward respectively, set the true_line to be */
/* the next line in the appropriate direction. */
/*---------------------------------------------------------------------*/
if (true_line == 0L
&& direction == DIRECTION_FORWARD)
true_line++;
if (true_line == CURRENT_FILE->number_lines+1L
&& direction == DIRECTION_BACKWARD)
true_line--;
if (true_line != CURRENT_VIEW->focus_line)
{
post_process_line(CURRENT_VIEW->focus_line);
pre_process_line(true_line);
}
number_lines = 0;
number_changes = 0;
number_of_changes = 0;
number_of_occ = 0;
start_col = 0;
last_true_line = true_line;
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
#else
curr = lll_find(CURRENT_FILE->first_line,true_line);
#endif
while(1)
{
loc = 0;
number_of_changes = number_of_occ = 0;
while(loc != (-1))
{
real_end = min(rec_len+len_old_str,CURRENT_VIEW->zone_end-1);
real_start = max(start_col,CURRENT_VIEW->zone_start-1);
if (rec_len < real_start && blank_field(old_str))
{
loc = 0;
rec_len = real_start+1;
}
else
{
loc = memfind(rec+real_start,old_str,(real_end-real_start+1),
len_old_str,
(CURRENT_VIEW->case_change == CASE_IGNORE) ? TRUE : FALSE,
CURRENT_VIEW->arbchar_status,
CURRENT_VIEW->arbchar_char);
}
if (loc != (-1))
{
start_col = loc+real_start;
if (number_of_changes <= long_n-1 && number_of_occ >= long_m-1)
{
/* the following block is done for change or confirm of sch */
if (!selective)
{
memdelchr(rec,start_col,rec_len,len_old_str);
/* rec_len -= len_old_str; */
rec_len = max(start_col,rec_len - len_old_str);
meminsmem(rec,new_str,len_new_str,start_col,max_line_length,rec_len);
rec_len += len_new_str;
if (rec_len > max_line_length)
{
rec_len = max_line_length;
loc = (-1);
}
start_col += len_new_str;
number_changes++;
number_of_changes++;
}
else
{
/* selective */
selective_rc = selective_change(old_str,len_old_str,new_str,len_new_str,
true_line,last_true_line,start_col);
last_true_line = true_line;
switch(selective_rc)
{
case QUITOK:
case RC_OK:
start_col += len_new_str;
number_changes++;
number_of_changes++;
if (rec_len > max_line_length)
{
rec_len = max_line_length;
loc = (-1);
}
break;
case SKIP:
start_col += len_old_str;
break;
case QUIT:
break;
}
if (selective_rc == QUIT || selective_rc == QUITOK)
break;
}
number_of_occ++;
}
else
{
start_col += len_old_str;
number_of_occ++;
}
if (number_of_changes > long_n-1)
/* || number_of_occ > long_n-1)*/
loc = (-1);
}
} /* end while */
if (number_of_changes != 0) /* changes made */
{
post_process_line(true_line);
number_lines++;
}
if (selective_rc == QUIT || selective_rc == QUITOK)
break;
true_line += (long)direction;
start_col = 0;
if (direction == DIRECTION_FORWARD)
{
if (true_line >= final_target)
break;
curr = curr->next;
}
else
{
if (true_line <= final_target)
break;
curr = curr->prev;
}
pre_process_line(true_line);
}
/*---------------------------------------------------------------------*/
/* If no changes were made, display error message and return. */
/*---------------------------------------------------------------------*/
if (number_changes == 0)
{
display_error(36,(char *)"");
pre_process_line(CURRENT_VIEW->focus_line);
#ifdef TRACE
trace_return();
#endif
return(RC_NO_LINES_CHANGED);
}
/*---------------------------------------------------------------------*/
/* If STAY is OFF, change the current and focus lines by the number */
/* of lines calculated from the target. */
/*---------------------------------------------------------------------*/
if (!CURRENT_VIEW->stay) /* stay is off */
{
if (equal((char *)"all",target,3))
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = num_lines+1L;
else
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line += num_lines-1L;
}
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
sprintf(old_str,"%d occurrence(s) changed on %d line(s)",number_changes,number_lines);
display_error(0,old_str);
#ifdef TRACE
trace_return();
#endif
if (CURRENT_TOF || CURRENT_BOF)
return(RC_TOF_EOF_REACHED);
else
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
short selective_change(char *old_str,int len_old_str,char *new_str,
int len_new_str,long true_line,long last_true_line,short start_col)
#else
short selective_change(old_str,len_old_str,new_str,len_new_str,true_line,last_true_line,start_col)
char *old_str;
int len_old_str;
char *new_str;
int len_new_str;
long true_line;
long last_true_line;
short start_col;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short y,x,rc;
long top_line,bottom_line;
unsigned short key;
bool changed;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:selective_change");
#endif
getyx(CURRENT_WINDOW_MAIN,y,x);
/* move cursor to old string a la cmatch */
/* display message */
/* accept key - C next, - N change, - Q to quit */
CURRENT_VIEW->focus_line = true_line;
/*---------------------------------------------------------------------*/
/* Check if the true_line is in the currently displayed window. */
/* If not, then change the current_line to the true_line. */
/*---------------------------------------------------------------------*/
top_line = (long)CURRENT_VIEW->current_line - (long)CURRENT_VIEW->current_row;
bottom_line = (long)CURRENT_VIEW->current_line + ((long)CURRENT_SCREEN.rows - (long)CURRENT_VIEW->current_row);
if (true_line < top_line
|| true_line >= bottom_line)
/* if (offset + y <= 0
|| offset + y >= CURRENT_SCREEN.rows)*/
{
CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
y = CURRENT_VIEW->current_row;
}
else
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (start_col >= CURRENT_VIEW->verify_col-1
&& start_col <= (CURRENT_SCREEN.cols+(CURRENT_VIEW->verify_col-1))-1)
x = start_col-(CURRENT_VIEW->verify_col-1);
else
{
x = CURRENT_SCREEN.cols / 2;
CURRENT_VIEW->verify_col = max(1,start_col-(short)x);
x = (start_col-(CURRENT_VIEW->verify_col-1));
}
key = 0;
changed = FALSE;
while(key == 0)
{
if (changed)
display_error(0,(char *)"Press 'N' for next,'C' to undo 'Q' to quit");
else
display_error(0,(char *)"Press 'N' for next,'C' to change 'Q' to quit");
touchwin(error_window);
show_page();
wmove(CURRENT_WINDOW_MAIN,y,x);
wrefresh(CURRENT_WINDOW_MAIN);
key = my_getch(CURRENT_WINDOW_MAIN);
switch(key)
{
case 'N':
case 'n':
if (changed)
rc = RC_OK;
else
rc = SKIP;
break;
case 'C':
case 'c':
if (changed)
{
memdelchr(rec,start_col,rec_len,len_new_str);
rec_len -= len_new_str;
meminsmem(rec,old_str,len_old_str,start_col,max_line_length,rec_len);
rec_len += len_old_str;
}
else
{
memdelchr(rec,start_col,rec_len,len_old_str);
rec_len -= len_old_str;
meminsmem(rec,new_str,len_new_str,start_col,max_line_length,rec_len);
rec_len += len_new_str;
}
changed = (changed) ? FALSE : TRUE;
key = 0;
break;
case 'Q':
case 'q':
if (changed)
rc = QUITOK;
else
rc = QUIT;
break;
default:
key = 0;
break;
}
}
error_on_screen = FALSE;
touchwin(foot);
wrefresh(foot);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int insert_new_line(char *line,int len,long num_lines,long true_line,bool start_left_col,bool make_current)
#else
int insert_new_line(line,len,num_lines,true_line,start_left_col,make_current)
char *line;
int len;
long num_lines;
long true_line;
bool start_left_col;
bool make_current;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
LINE *curr,*save_curr;
unsigned short x,y;
bool on_bottom=FALSE;
int rc,new_col;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:insert_new_line");
#endif
/*---------------------------------------------------------------------*/
/* If we are on the 'Bottom of File' line reduce the true_line by 1 */
/* so that the new line is added before the bottom line. */
/*---------------------------------------------------------------------*/
if (true_line == CURRENT_FILE->number_lines+1L)
true_line--;
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for the true_line. */
/* This is the line after which the line(s) are to be added. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
#else
curr = lll_find(CURRENT_FILE->first_line,true_line);
#endif
/*---------------------------------------------------------------------*/
/* Insert into the linked list the number of lines specified. All lines*/
/* will contain a blank line and a length of zero. */
/*---------------------------------------------------------------------*/
save_curr = curr;
for (i=0;i<num_lines;i++)
{
if ((curr = add_line(CURRENT_FILE->first_line,curr,line,len)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
}
/*---------------------------------------------------------------------*/
/* Fix the positioning of the marked block (if there is one and it is */
/* in the current view). */
/*---------------------------------------------------------------------*/
adjust_marked_lines(TRUE,true_line,num_lines);
adjust_pending_prefix(CURRENT_VIEW,TRUE,true_line,num_lines);
/*---------------------------------------------------------------------*/
/* Increment the number of lines counter for the current file and the */
/* number of alterations. */
/*---------------------------------------------------------------------*/
if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
CURRENT_FILE->number_lines += num_lines;
/*---------------------------------------------------------------------*/
/* Sort out focus and current line. */
/*---------------------------------------------------------------------*/
CURRENT_VIEW->focus_line = true_line + 1;
switch(CURRENT_VIEW->current_window)
{
case WINDOW_COMMAND:
if (make_current)
CURRENT_VIEW->current_line = true_line + 1;
break;
case WINDOW_MAIN:
if (!in_profile)
getyx(CURRENT_WINDOW,y,x);
if (y == CURRENT_SCREEN.rows - 1)
CURRENT_VIEW->current_line++;
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
new_col = x;
if (!start_left_col)
{
if (CURRENT_VIEW->newline_aligned)
{
new_col = memne(save_curr->line,' ',save_curr->length);
if (new_col == (-1))
new_col = 0;
/*---------------------------------------------------------------------*/
/* Special case when right margin is > than screen width... */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->verify_start != CURRENT_VIEW->verify_col)
{
/*---------------------------------------------------------------------*/
/* If the new column position will be on the same page... */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->verify_col < new_col
&& CURRENT_VIEW->verify_col + CURRENT_SCREEN.screen_cols > new_col)
new_col = (new_col - CURRENT_VIEW->verify_col) + 1;
else
{
x = CURRENT_SCREEN.cols / 2;
CURRENT_VIEW->verify_col = max(1,new_col - (int)x + 2);
new_col = (CURRENT_VIEW->verify_col == 1) ? new_col : x - 1;
}
}
}
else
{
new_col = 0;
CURRENT_VIEW->verify_col = 1;
}
}
/*---------------------------------------------------------------------*/
/* Move the cursor to where it should be and display the page. */
/*---------------------------------------------------------------------*/
wmove(CURRENT_WINDOW,y,new_col);
break;
case WINDOW_PREFIX:
if (!in_profile)
{
getyx(CURRENT_WINDOW,y,x);
if (y == CURRENT_SCREEN.rows - 1)
CURRENT_VIEW->current_line++;
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
wmove(CURRENT_WINDOW,y,0);
}
break;
}
pre_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Re-display the main window. */
/*---------------------------------------------------------------------*/
show_page();
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_os_command(char *cmd,bool quiet,bool pause)
#else
int execute_os_command(cmd,quiet,pause)
char *cmd;
bool quiet;
bool pause;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#if defined(DOS) || defined(OS2)
#define SHELL "COMSPEC"
#else
#define SHELL "SHELL"
#endif
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_os_command");
#endif
if (!quiet)
{
attrset(A_NORMAL);
touchwin(stdscr);
wmove(stdscr,0,0);
addch(' ');
wmove(stdscr,1,0);
wrefresh(stdscr); /* clear screen */
suspend_curses();
}
if (allocate_temp_space(strlen(cmd),TEMP_TEMP_CMD) != RC_OK)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if (strcmp(cmd,"") == 0)
strcpy(temp_cmd,getenv(SHELL));
else
strcpy(temp_cmd,cmd);
#ifdef UNIX
if (strcmp(temp_cmd,"") == 0) /* no SHELL env variable set */
{
printf("No SHELL environment variable set - using /bin/sh\n");
fflush(stdout);
strcpy(temp_cmd,"/bin/sh");
}
#endif
if (quiet)
{
#ifdef UNIX
strcat(temp_cmd," > /dev/null");
#endif
#if defined(DOS) || defined(OS2)
strcat(temp_cmd," > nul:");
#endif
}
system(temp_cmd);
if (pause)
{
printf("\n\n%s",HIT_ANY_KEY);
fflush(stdout);
}
if (!quiet)
{
resume_curses();
if (pause)
wgetch(stdscr);
restore_THE();
}
draw_cursor(ON);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_makecurr(long line)
#else
int execute_makecurr(line)
long line;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short y,x;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_makecurr");
#endif
post_process_line(CURRENT_VIEW->focus_line);
CURRENT_VIEW->current_line = line;
if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
getyx(CURRENT_WINDOW,y,x);
else
getyx(CURRENT_WINDOW_MAIN,y,x);
show_page();
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
wmove(CURRENT_WINDOW,y,x);
else
wmove(CURRENT_WINDOW_MAIN,y,x);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_shift_command(int shift_left,int num_cols,long true_line,long num_lines)
#else
int execute_shift_command(shift_left,num_cols,true_line,num_lines)
int shift_left,num_cols;
long true_line,num_lines;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short y,x;
LINE *curr;
long abs_num_lines = (num_lines < 0L ? -num_lines : num_lines);
long i;
register int j;
int actual_cols;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_shift_command");
#endif
post_process_line(CURRENT_VIEW->focus_line);
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
getyx(CURRENT_WINDOW_MAIN,y,x);
else
getyx(CURRENT_WINDOW,y,x);
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
#else
curr = lll_find(CURRENT_FILE->first_line,true_line);
#endif
for (i=0L;i<abs_num_lines;i++)
{
memset(rec,' ',max_line_length);
memcpy(rec,curr->line,curr->length);
rec_len = curr->length;
if (shift_left)
{
actual_cols = min(num_cols,rec_len);
memdelchr(rec,CURRENT_VIEW->zone_start-1,rec_len,actual_cols);
rec_len -= actual_cols;
}
else
{
for (j=0;j<num_cols;j++)
meminschr(rec,' ',CURRENT_VIEW->zone_start-1,max_line_length,rec_len++);
rec_len = min(rec_len,max_line_length);
}
/*---------------------------------------------------------------------*/
/* Increment the alteration counters... */
/*---------------------------------------------------------------------*/
if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*---------------------------------------------------------------------*/
/* Add the old line contents to the line recovery list. */
/*---------------------------------------------------------------------*/
add_to_recovery_list(curr->line,curr->length);
/*---------------------------------------------------------------------*/
/* Realloc the dynamic memory for the line if the line is now longer. */
/*---------------------------------------------------------------------*/
if (rec_len > curr->length)
/* what if realloc fails ?? */
curr->line = (char *)realloc((void *)curr->line,(rec_len+1)*sizeof(char));
/*---------------------------------------------------------------------*/
/* Copy the contents of rec into the line. */
/*---------------------------------------------------------------------*/
memcpy(curr->line,rec,rec_len);
curr->length = rec_len;
*(curr->line+rec_len) = '\0';
if (num_lines < 0L)
curr = curr->prev;
else
curr = curr->next;
}
/*---------------------------------------------------------------------*/
/* If STAY is OFF, change the current and focus lines by the number */
/* of lines calculated from the target. */
/*---------------------------------------------------------------------*/
if (!CURRENT_VIEW->stay) /* stay is off */
{
CURRENT_VIEW->focus_line = min(CURRENT_VIEW->focus_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
CURRENT_VIEW->current_line = min(CURRENT_VIEW->current_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
}
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
wmove(CURRENT_WINDOW_MAIN,y,x);
else
wmove(CURRENT_WINDOW,y,x);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_change_case(char *params,char which_case)
#else
int execute_change_case(params,which_case)
char *params;
char which_case;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define LOW_PARAMS 1
char *word[LOW_PARAMS+1];
char parm[LOW_PARAMS];
register int i;
unsigned short num_params;
long num_lines,true_line;
unsigned short x,y;
int direction;
LINE *curr;
bool block_delete=FALSE;
int start_col,end_col;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_change_case");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. */
/* Valid values are: a target or "block". */
/* If no parameter is supplied, 1 is assumed. */
/*---------------------------------------------------------------------*/
num_params = param_split(params,word,LOW_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
num_params = 1;
word[0] = (char *)"1";
}
if (equal((char *)"block",word[0],5))
{
if (marked_block(TRUE) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
num_lines = MARK_VIEW->mark_end_line-MARK_VIEW->mark_start_line+1L;
true_line = MARK_VIEW->mark_start_line;
direction = DIRECTION_FORWARD;
if (MARK_VIEW->mark_type == M_LINE)
{
start_col = CURRENT_VIEW->zone_start-1;
end_col = CURRENT_VIEW->zone_end-1;
}
else
{
start_col = MARK_VIEW->mark_start_col-1;
end_col = MARK_VIEW->mark_end_col-1;
}
}
else
{
if (equal((char *)"all",word[0],3))
true_line = 1L;
else
true_line = get_true_line();
if ((num_lines = valid_target(word[0],true_line)) == TARGET_ERROR)
{
display_error(4,(char *)word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (num_lines == TARGET_NOT_FOUND)
{
display_error(17,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_TARGET_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* Determine in which direction we are working. */
/*---------------------------------------------------------------------*/
if (num_lines < 0)
{
direction = DIRECTION_BACKWARD;
num_lines = num_lines * (-1L);
}
else
direction = DIRECTION_FORWARD;
/*---------------------------------------------------------------------*/
/* Check from which window the command was issued and make adjustments */
/* as required. */
/* Commands issued from the command window relate to the current line, */
/* commands issued from either the prefix or main window relate to the */
/* focus line. */
/*---------------------------------------------------------------------*/
if (!equal((char *)"all",word[0],3))
{
if (CURRENT_VIEW->current_window == WINDOW_COMMAND
|| in_profile)
{
if (TOF(true_line))
{
true_line++;
if (!valid_integer(word[0]))
num_lines--;
}
if (BOF(true_line))
{
true_line--;
if (!valid_integer(word[0]))
num_lines--;
}
}
else
{
if (TOF(true_line) || BOF(true_line))
{
display_error(38,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
}
}
start_col = CURRENT_VIEW->zone_start-1;
end_col = CURRENT_VIEW->zone_end-1;
}
post_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for the true_line. */
/* This is the first line to change. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
#else
curr = lll_find(CURRENT_FILE->first_line,true_line);
#endif
/*---------------------------------------------------------------------*/
/* Change the values in the linked list for the specified number of */
/* lines in the direction specified. */
/*---------------------------------------------------------------------*/
for (i=0;i<num_lines;i++)
{
add_to_recovery_list(curr->line,curr->length);
change_case(curr->line,max(0,start_col),min(curr->length-1,end_col),which_case);
if (direction == DIRECTION_FORWARD)
curr = curr->next;
else
curr = curr->prev;
}
/*---------------------------------------------------------------------*/
/* If STAY is OFF, change the current and focus lines by the number */
/* of lines calculated from the target. */
/*---------------------------------------------------------------------*/
if (!CURRENT_VIEW->stay) /* stay is off */
{
if (equal((char *)"all",word[0],3))
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = num_lines+1L;
else
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line += num_lines-1L;
}
/*---------------------------------------------------------------------*/
/* If we are in the profile, then don't do any more processing. */
/*---------------------------------------------------------------------*/
if (in_profile)
{
pre_process_line(CURRENT_VIEW->focus_line);
#ifdef TRACE
trace_return();
#endif
if (CURRENT_TOF || CURRENT_BOF)
return(RC_TOF_EOF_REACHED);
else
return(RC_OK);
}
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
{
getyx(CURRENT_WINDOW,y,x);
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
wmove(CURRENT_WINDOW,y,x);
}
#ifdef TRACE
trace_return();
#endif
if (CURRENT_TOF || CURRENT_BOF)
return(RC_TOF_EOF_REACHED);
else
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int change_case(char *str,int start,int end,char which_case)
#else
int change_case(str,start,end,which_case)
char *str;
int start,end;
char which_case;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
bool altered = FALSE;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:change_case");
#endif
for (i=start;i<end+1;i++)
{
switch(which_case)
{
case CASE_UPPER:
if (islower(*(str+i)))
{
*(str+i) = toupper(*(str+i));
altered = TRUE;
}
break;
case CASE_LOWER:
if (isupper(*(str+i)))
{
*(str+i) = tolower(*(str+i));
altered = TRUE;
}
break;
}
}
/*---------------------------------------------------------------------*/
/* Increment the number of alterations count if anything cahnged. */
/*---------------------------------------------------------------------*/
if (altered)
if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int rearrange_line_blocks(char command,char source,
long start_line,long end_line,long dest_line,int num_occ,
VIEW_DETAILS *src_view,VIEW_DETAILS *dst_view)
#else
int rearrange_line_blocks(command,source,start_line,end_line,dest_line,num_occ,src_view,dst_view)
char command,source;
long start_line,end_line,dest_line;
int num_occ;
VIEW_DETAILS *src_view,*dst_view;
#endif
/***********************************************************************/
/* Parameters: */
/* command: the command being executed; COPY,DELETE,DUPLICATE,MOVE */
/* source: where the command is executed; COMMAND, PREFIX, BLOCK */
/* start_line: the first line (or only line) number to be acted on */
/* end_line: the last line number to be acted on */
/* dest_line: the destination line for copy,move and duplicate. For */
/* delete this is not applicable. */
/* num_occ: the number of times to execute the command; only for DUP*/
/***********************************************************************/
{
#define VIEW_CURRENT_WINDOW(view) (view->win[vd_current->current_window])
/*--------------------------- local data ------------------------------*/
register int i,j,k;
int rc;
static unsigned short y,x;
bool dst_inside_src,lines_added,reset_block;
bool dest_in_block=FALSE;
int direction;
long num_lines,off,adjust_line=dest_line;
LINE *curr_src,*curr_dst;
LINE *save_curr_src,*save_curr_dst;
FILE_DETAILS *src_file,*dst_file;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:rearrange_line_blocks");
#endif
src_file = src_view->file_for_view;
dst_file = dst_view->file_for_view;
switch(source)
{
case SOURCE_BLOCK:
case SOURCE_BLOCK_RESET:
if (source == SOURCE_BLOCK)
reset_block = FALSE;
else
reset_block = TRUE;
break;
default:
break;
}
/*---------------------------------------------------------------------*/
/* This block of commands is for copying lines... */
/*---------------------------------------------------------------------*/
switch(command)
{
case COMMAND_COPY:
case COMMAND_MOVE_COPY_SAME:
case COMMAND_MOVE_COPY_DIFF:
case COMMAND_DUPLICATE:
lines_added = TRUE;
switch(source)
{
case SOURCE_BLOCK:
case SOURCE_BLOCK_RESET:
if (src_view == dst_view
&& dest_line >= start_line
&& dest_line < end_line)
dest_in_block = TRUE;
break;
case SOURCE_PREFIX:
if (dest_line >= start_line
&& dest_line < end_line)
dest_in_block = TRUE;
break;
default:
break;
}
/*---------------------------------------------------------------------*/
/* If the destination line is within the marked block then we have to */
/* handle the processing of the src_curr pointer differently. */
/*---------------------------------------------------------------------*/
if (dest_in_block)
{
dst_inside_src = TRUE;
off = dest_line - start_line;
}
else
dst_inside_src = FALSE;
num_lines = end_line - start_line + 1L;
#ifdef USE_VOID
save_curr_src = (LINE *)ll_find((void *)src_file->first_line,start_line);
#else
save_curr_src = lll_find(src_file->first_line,start_line);
#endif
#ifdef USE_VOID
save_curr_dst = (LINE *)ll_find((void *)dst_file->first_line,dest_line);
#else
save_curr_dst = lll_find(dst_file->first_line,dest_line);
#endif
for (k=0;k<num_occ;k++)
{
curr_src = save_curr_src;
curr_dst = save_curr_dst;
for (i=0;i<num_lines;i++)
{
if ((curr_dst = add_line(dst_file->first_line,curr_dst,
curr_src->line,curr_src->length)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* If moving lines within the same file, move any line name with the */
/* line also. */
/*---------------------------------------------------------------------*/
if (command == COMMAND_MOVE_COPY_SAME)
{
if (curr_src->name != (char *)NULL)
{
curr_dst->name = curr_src->name;
curr_src->name = (char *)NULL;
}
}
if (dst_inside_src && i == off)
for (j=0;j<off+1;j++)
curr_src = curr_src->next;
curr_src = curr_src->next;
}
}
dst_file->number_lines += num_lines*num_occ;
break;
default:
break;
}
/*---------------------------------------------------------------------*/
/* This block of commands is for deleting lines... */
/*---------------------------------------------------------------------*/
switch(command)
{
case COMMAND_DELETE:
case COMMAND_MOVE_DELETE_SAME:
case COMMAND_MOVE_DELETE_DIFF:
lines_added = FALSE;
if (start_line > end_line)
{
direction = DIRECTION_BACKWARD;
num_lines = start_line - end_line + 1L;
}
else
{
direction = DIRECTION_FORWARD;
num_lines = end_line - start_line + 1L;
}
#ifdef USE_VOID
curr_dst = (LINE *)ll_find((void *)dst_file->first_line,start_line);
#else
curr_dst = lll_find(dst_file->first_line,start_line);
#endif
for (i=0;i<num_lines;i++)
{
if (command != COMMAND_MOVE_DELETE_SAME)
add_to_recovery_list(curr_dst->line,curr_dst->length);
curr_dst = delete_line(dst_file->first_line,curr_dst,direction);
}
dst_file->number_lines -= num_lines*num_occ;
break;
default:
break;
}
/*---------------------------------------------------------------------*/
/* Increment alteration count for all but COMMAND_MOVE_COPY_SAME... */
/*---------------------------------------------------------------------*/
if (command != COMMAND_MOVE_COPY_SAME)
{
if ((rc = increment_alt(dst_file)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
/*---------------------------------------------------------------------*/
/* This block of commands is for sorting out cursor position... */
/*---------------------------------------------------------------------*/
switch(command)
{
case COMMAND_COPY:
case COMMAND_MOVE_COPY_SAME:
case COMMAND_MOVE_COPY_DIFF:
case COMMAND_DUPLICATE:
if (IN_VIEW(dst_view,dest_line))
{
dst_view->focus_line = dest_line+1L;
}
if (dst_view->current_window != WINDOW_COMMAND)
{
getyx(VIEW_CURRENT_WINDOW(dst_view),y,x);
if (y == CURRENT_SCREEN.rows-1)/* on bottom line of window */
{
dst_view->current_line = dst_view->focus_line;
y = dst_view->current_row;
}
else
y = get_row_for_focus_line(dst_view->current_row,
dst_view->focus_line,
dst_view->current_line);
}
break;
case COMMAND_DELETE:
case COMMAND_MOVE_DELETE_SAME:
case COMMAND_MOVE_DELETE_DIFF:
if (dst_view->focus_line >= start_line
&& dst_view->focus_line <= end_line)
{
if (IN_VIEW(dst_view,dest_line))
{
if (dst_view->current_line > dst_file->number_lines+1L)
dst_view->current_line -= num_lines;
dst_view->focus_line = dest_line;
}
else
{
if (dest_line > dst_file->number_lines)
dst_view->focus_line = dst_view->current_line = dst_file->number_lines;
else
dst_view->focus_line = dst_view->current_line = dest_line;
}
}
else
{
dest_line = (dst_view->focus_line < start_line ? dst_view->focus_line : dst_view->focus_line - num_lines);
if (IN_VIEW(dst_view,dest_line))
{
if (dst_view->current_line > dst_file->number_lines+1L)
dst_view->current_line -= num_lines;
dst_view->focus_line = dest_line;
}
else
{
if (dest_line > dst_file->number_lines)
dst_view->focus_line = dst_view->current_line = dst_file->number_lines;
else
dst_view->focus_line = dst_view->current_line = dest_line;
}
}
if (dst_file->number_lines == 0L)
dst_view->focus_line = dst_view->current_line = 0L;
if (dst_view->current_window != WINDOW_COMMAND)
{
getyx(VIEW_CURRENT_WINDOW(dst_view),y,x);
y = get_row_for_focus_line(dst_view->current_row,
dst_view->focus_line,
dst_view->current_line);
}
/*---------------------------------------------------------------------*/
/* This is set here so that the adjust_pending_prefix command will work*/
/*---------------------------------------------------------------------*/
if (direction == DIRECTION_BACKWARD)
adjust_line = end_line;
else
adjust_line = start_line;
break;
default:
break;
}
/*---------------------------------------------------------------------*/
/* This block of commands is for adjusting prefix and block lines... */
/*---------------------------------------------------------------------*/
switch(source)
{
case SOURCE_BLOCK:
case SOURCE_BLOCK_RESET:
adjust_pending_prefix(dst_view,lines_added,adjust_line,num_lines*num_occ);
if (command == COMMAND_MOVE_DELETE_SAME)
adjust_marked_lines(lines_added,adjust_line,num_lines*num_occ);
else
if (command != COMMAND_MOVE_DELETE_DIFF)
{
MARK_VIEW->mark_start_line = MARK_VIEW->mark_end_line = (-1L);
MARK_VIEW->mark_start_col = MARK_VIEW->mark_end_col = (-1);
dst_view->mark_start_line = dest_line + 1L;
dst_view->mark_end_line = dest_line + num_lines;
dst_view->mark_start_col = dst_view->mark_end_col = (-1);
dst_view->mark_type = M_LINE;
dst_view->focus_line = dst_view->mark_start_line;
MARK_VIEW = dst_view;
/*---------------------------------------------------------------------*/
/* The following does a 'reset block' in the current view. */
/*---------------------------------------------------------------------*/
if (reset_block)
{
dst_view->mark_start_line = dst_view->mark_end_line = (-1L);
dst_view->mark_start_col = dst_view->mark_end_col = (-1);
MARK_VIEW = (VIEW_DETAILS *)NULL;
}
}
break;
case SOURCE_PREFIX:
case SOURCE_COMMAND:
adjust_marked_lines(lines_added,adjust_line,num_lines*num_occ);
adjust_pending_prefix(dst_view,lines_added,adjust_line,num_lines*num_occ);
break;
}
if (command != COMMAND_MOVE_DELETE_DIFF)
pre_process_line(dst_view->focus_line);
/*---------------------------------------------------------------------*/
/* If run from the profile, exit here. */
/*---------------------------------------------------------------------*/
if (in_profile)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
if (command != COMMAND_MOVE_DELETE_DIFF
&& command != COMMAND_MOVE_COPY_SAME)
show_page();
if (dst_view->current_window != WINDOW_COMMAND)
wmove(VIEW_CURRENT_WINDOW(dst_view),y,x);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_set_point(char *name,long true_line,bool point_on)
#else
int execute_set_point(name,true_line,point_on)
char *name;
long true_line;
bool point_on;
#endif
/***********************************************************************/
/* Parameters: */
/* name: the name of the line to be processed */
/* true_line: the line number of the line */
/* point_on: indicates if the line name is to be turned on or off */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
long dummy;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_set_point");
#endif
if (point_on)
{
/*---------------------------------------------------------------------*/
/* Find a line that already has the same name. If one exists, remove */
/* the name. */
/*---------------------------------------------------------------------*/
if ((curr = find_named_line(name,&dummy)) != (LINE *)NULL)
{
free(curr->name);
curr->name = (char *)NULL;
}
/*---------------------------------------------------------------------*/
/* Allocate space for the name and attach it to the true_line. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
#else
curr = lll_find(CURRENT_FILE->first_line,true_line);
#endif
if ((curr->name=(char *)malloc(strlen(name)+1)) == (char *)NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
strcpy(curr->name,name);
}
else
{
/*---------------------------------------------------------------------*/
/* Find a line that already has the same name. If one exists, remove */
/* the name otherwise display an error. */
/*---------------------------------------------------------------------*/
if ((curr = find_named_line(name,&dummy)) != (LINE *)NULL)
{
free(curr->name);
curr->name = (char *)NULL;
}
else
{
display_error(60,name);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_wrap_word(unsigned short col)
#else
int execute_wrap_word(col)
unsigned short col;
#endif
/***********************************************************************/
/* Parameters: col - current column position within rec */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
unsigned short y,x;
int col_break,cursor_offset,new_col;
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_wrap_word");
#endif
/*---------------------------------------------------------------------*/
/* All characters from the current word to the end of the line will be */
/* wrapped and a new line created. If the cursor is on a space, the */
/* first non-blank will appear in the paragraph column. If the cursor */
/* is in a word, the beginning of the word will appear in the paragraph*/
/* column, and the cursor will appear 1 character to the right of the */
/* last character entered. */
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for the focus_line. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
#else
curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
#endif
/*---------------------------------------------------------------------*/
/* Determine where to start splitting the line in relation to right */
/* margin (not current column)... */
/*---------------------------------------------------------------------*/
col_break = (-1);
if (rec[CURRENT_VIEW->margin_right-1] == ' ')
{
cursor_offset = 0;
for (i=CURRENT_VIEW->margin_right-1;i<rec_len;i++)
{
if (rec[i] != ' ')
{
col_break = i;
break;
}
}
if (col_break == (-1))
{
col_break = col;
add_line(CURRENT_FILE->first_line,curr,"",0);
}
else
add_line(CURRENT_FILE->first_line,curr,(rec+col_break),
rec_len - col_break);
cursor_offset = col - col_break;
}
else
/*---------------------------------------------------------------------*/
/* Find start of word at the right margin... */
/*---------------------------------------------------------------------*/
{
/* for (i=CURRENT_VIEW->margin_right-1;i>0;i--) to start of line */
for (i=CURRENT_VIEW->margin_right-1;i>CURRENT_VIEW->margin_left-1;i--) /* to left margin */
{
if (rec[i] == ' ')
{
col_break = i+1;
break;
}
}
/*---------------------------------------------------------------------*/
/* If the word begins in column 1, then look for the first word break */
/* after the right margin, to break there. */
/*---------------------------------------------------------------------*/
if (col_break == (-1))
{
for (i=0;i<rec_len;i++)
if (rec[i] == ' ')
col_break = i;
}
/*---------------------------------------------------------------------*/
/* If there is no word break, don't attempt any wrap. */
/*---------------------------------------------------------------------*/
if (col_break == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
cursor_offset = col - col_break;
add_line(CURRENT_FILE->first_line,curr,(rec+col_break),
rec_len - col_break);
}
CURRENT_FILE->number_lines++;
/*---------------------------------------------------------------------*/
/* Blank out that portion of rec that has been copied to the new line */
/* and copy rec back into linked list. */
/*---------------------------------------------------------------------*/
for (i=col_break;i<rec_len;i++)
rec[i] = ' ';
rec_len = col_break;
post_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Make the newly added line the focus line. This also copies the */
/* contents of the line into rec. */
/*---------------------------------------------------------------------*/
Down_arrow((char *)"");
for (i=1;i<PARACOL;i++)
meminschr(rec,' ',0,max_line_length,rec_len++);
rec_len = min(rec_len,max_line_length);
/*---------------------------------------------------------------------*/
/* Determine cursor location relative to start of rec (0 based). */
/*---------------------------------------------------------------------*/
getyx(CURRENT_WINDOW,y,x);
new_col = PARACOL+cursor_offset-1;
/*---------------------------------------------------------------------*/
/* Special case when right margin is > than screen width... */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->verify_start != CURRENT_VIEW->verify_col)
{
/*---------------------------------------------------------------------*/
/* If the new column position will be on the same page... */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->verify_col < new_col
&& CURRENT_VIEW->verify_col + CURRENT_SCREEN.screen_cols > new_col)
new_col = (new_col - CURRENT_VIEW->verify_col) + 1;
else
{
x = CURRENT_SCREEN.cols / 2;
CURRENT_VIEW->verify_col = max(1,new_col - x + 2);
new_col = (CURRENT_VIEW->verify_col == 1) ? new_col : x - 1;
}
}
/*---------------------------------------------------------------------*/
/* Move the cursor to where it should be and display the page. */
/*---------------------------------------------------------------------*/
wmove(CURRENT_WINDOW,y,new_col);
show_page();
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_split_join(bool action,bool aligned)
#else
int execute_split_join(action,aligned)
bool action,aligned;
#endif
/***********************************************************************/
/* Parameters: action - split or join line */
/* aligned - whether to align text or not */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
int num_cols,num_blanks_focus,num_blanks_next;
unsigned short x,y,col;
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("execute.c: execute_split_join");
#endif
if (CURRENT_VIEW->current_window != WINDOW_MAIN)
{
display_error(38,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
/*---------------------------------------------------------------------*/
/* Reject the command if on the top or bottom line. */
/*---------------------------------------------------------------------*/
if (FOCUS_TOF || FOCUS_BOF)
{
display_error(38,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
/*---------------------------------------------------------------------*/
/* Copy any changes in the focus line to the linked list. */
/*---------------------------------------------------------------------*/
post_process_line(CURRENT_VIEW->focus_line);
/*---------------------------------------------------------------------*/
/* Find the current LINE pointer for the focus_line. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
#else
curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
#endif
getyx(CURRENT_WINDOW,y,x);
col = (x+CURRENT_VIEW->verify_col-1);
switch(action)
{
case SPLIT_TRUE:
memset(rec,' ',max_line_length);
memcpy(rec,curr->line+col,curr->length);
rec_len = curr->length-col;
/*---------------------------------------------------------------------*/
/* Calculate the number of leading blanks on the current line so that */
/* the new line can have this many blanks prepended to align properly. */
/*---------------------------------------------------------------------*/
if (aligned)
{
num_cols = memne(curr->line,' ',curr->length);
if (num_cols == (-1))
num_cols = 0;
for (i=0;i<num_cols;i++)
meminschr(rec,' ',0,max_line_length,rec_len++);
rec_len = min(rec_len,max_line_length);
}
add_line(CURRENT_FILE->first_line,curr,(rec),
rec_len);
CURRENT_FILE->number_lines++;
pre_process_line(CURRENT_VIEW->focus_line);
Sos_delend("");
post_process_line(CURRENT_VIEW->focus_line);
break;
case SPLIT_FALSE:
if (curr->next->next == NULL)
{
/*---------------------------------------------------------------------*/
/* Trying to join with the bottom of file line. */
/*---------------------------------------------------------------------*/
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
/*---------------------------------------------------------------------*/
/* Calculate the number of leading blanks for the focus line and also */
/* for the line to be joined. To align the join properly, we have to */
/* remove up the number of leading blanks in the focus line from the */
/* beginning of the line to be joined. */
/*---------------------------------------------------------------------*/
if (aligned)
{
num_blanks_focus = memne(curr->line,' ',curr->length);
if (num_blanks_focus == (-1))
num_blanks_focus = 0;
num_blanks_next = memne(curr->next->line,' ',curr->length);
if (num_blanks_next == (-1))
num_blanks_next = 0;
num_cols = min(num_blanks_focus,num_blanks_next);
}
else
num_cols = 0;
meminsmem(rec,curr->next->line+num_cols,curr->next->length-num_cols,
col,max_line_length,col);
rec_len = min(max_line_length,col+curr->next->length-num_cols);
post_process_line(CURRENT_VIEW->focus_line);
curr = delete_line(CURRENT_FILE->first_line,curr->next,DIRECTION_BACKWARD);
/*---------------------------------------------------------------------*/
/* If on the bottom line, use the previous line. */
/*---------------------------------------------------------------------*/
if (CURRENT_BOF)
{
CURRENT_VIEW->current_line--;
y++;
}
/*---------------------------------------------------------------------*/
/* Decrement the number of lines counter for the current file and move */
/* the cursor to the appropriate line. */
/*---------------------------------------------------------------------*/
CURRENT_FILE->number_lines--;
wmove(CURRENT_WINDOW,y,x);
break;
}
show_page();
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_put(char *params,bool putdel)
#else
int execute_put(params,putdel)
char *params;
bool putdel;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern char *tempfilename;
extern char sp_path[MAX_FILE_NAME+1] ;
extern char sp_fname[MAX_FILE_NAME+1] ;
/*--------------------------- local data ------------------------------*/
#define PUT_PARAMS 2
char *word[PUT_PARAMS+1];
unsigned short num_params;
long num_lines,true_line;
char append;
char *filename;
int rc,start_col=0,end_col=max_line_length;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("execute.c: execute_put");
#endif
num_params = param_split(params,word,PUT_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
num_params = 1;
word[0] = (char *)"1";
}
if (num_params > 2)
{
display_error(1,word[2]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if ((num_lines = valid_target(word[0],get_true_line())) == TARGET_ERROR)
{
display_error(4,word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (strcmp(word[1],"") == 0) /* no fileid supplied */
{
append = NO;
filename = tempfilename;
}
else
{
if ((rc = splitpath(word[1])) != RC_OK)
{
display_error(10,word[1]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
strcpy(temp_cmd,sp_path);
strcat(temp_cmd,sp_fname);
filename = temp_cmd;
append = YES;
}
/*---------------------------------------------------------------------*/
/* Get the true_line here. If the target is BLOCK, then the true_line */
/* will be set to the first line of the marked block. */
/*---------------------------------------------------------------------*/
true_line = get_true_line();
/*---------------------------------------------------------------------*/
/* If the target is "all", set number of lines to 0L. This ensures that*/
/* save_file() will write out the whole file. */
/*---------------------------------------------------------------------*/
if (equal((char *)"all",word[0],3))
num_lines = 0L;
else
/*---------------------------------------------------------------------*/
/* If the target is "block", the marked block must be a line block in */
/* the current view. */
/*---------------------------------------------------------------------*/
if (equal((char *)"block",word[0],5))
{
/*---------------------------------------------------------------------*/
/* Validate the marked block. */
/*---------------------------------------------------------------------*/
if (marked_block(TRUE) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
/*---------------------------------------------------------------------*/
/* If the marked block is a BOX block, set up the left and right column*/
/* values. */
/*---------------------------------------------------------------------*/
if (MARK_VIEW->mark_type == M_BOX)
{
start_col = MARK_VIEW->mark_start_col-1;
end_col = MARK_VIEW->mark_end_col-1;
}
true_line = MARK_VIEW->mark_start_line;
num_lines = MARK_VIEW->mark_end_line - MARK_VIEW->mark_start_line + 1;
}
else
/*---------------------------------------------------------------------*/
/* For other targets, adjust for beginning on TOF or EOF and for the */
/* direction of the command. */
/*---------------------------------------------------------------------*/
{
if (TOF(true_line))
{
true_line++;
if (!valid_integer(word[0]))
num_lines--;
}
if (BOF(true_line))
{
true_line--;
if (!valid_integer(word[0]))
(num_lines < 0L) ? num_lines++ : num_lines--;
}
if (num_lines < 0L)
{
num_lines = -num_lines;
true_line = true_line - num_lines + 1L;
}
}
post_process_line(CURRENT_VIEW->focus_line);
if ((rc = save_file(CURRENT_FILE,filename,YES,num_lines,true_line,append,start_col,end_col)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*---------------------------------------------------------------------*/
/* If we are executing a putd command, delete the target... */
/*---------------------------------------------------------------------*/
if (putdel)
rc = DeleteLine(word[0]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int execute_macro(char *params,bool error_on_not_found)
#else
int execute_macro(params,error_on_not_found)
char *params;
bool error_on_not_found;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern char in_macro;
extern char number_of_files;
/*--------------------------- local data ------------------------------*/
int rc;
int errnum=0;
FILE *fp;
#define MAC_PARAMS 2
char *word[MAC_PARAMS+1];
unsigned short num_params;
char *macroname;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("execute.c: execute_macro");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters. At least 1 must be present, the filename. */
/*---------------------------------------------------------------------*/
num_params = param_split(params,word,MAC_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
display_error(3,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* Allocate some space for macroname... */
/*---------------------------------------------------------------------*/
if ((macroname = (char *)malloc((MAX_FILE_NAME+1)*sizeof(char))) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Find the fully qualified file name for the supplied macro name. */
/*---------------------------------------------------------------------*/
rc = get_valid_macro_file_name(word[0],macroname,&errnum);
/*---------------------------------------------------------------------*/
/* Validate the return code... */
/*---------------------------------------------------------------------*/
switch(rc)
{
/*---------------------------------------------------------------------*/
/* If RC_OK, continue to process the macro... */
/*---------------------------------------------------------------------*/
case RC_OK:
break;
/*---------------------------------------------------------------------*/
/* If RC_FILE_NOT_FOUND and IMPOS is not on, display an error and exit.*/
/* If IMPOS is on, just return without displaying an error. */
/*---------------------------------------------------------------------*/
case RC_FILE_NOT_FOUND:
if (error_on_not_found)
/* if (!CURRENT_VIEW->imp_os)*/
display_error(errnum,macroname);
free(macroname);
#ifdef TRACE
trace_return();
#endif
return(rc);
break;
/*---------------------------------------------------------------------*/
/* All other cases, display error and return. */
/*---------------------------------------------------------------------*/
default:
free(macroname);
display_error(errnum,macroname);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*---------------------------------------------------------------------*/
/* Set in_macro = TRUE to stop multiple show_page()s being performed. */
/*---------------------------------------------------------------------*/
in_macro = TRUE;
/*---------------------------------------------------------------------*/
/* If REXX is supported, process the macro as a REXX macro... */
/*---------------------------------------------------------------------*/
#if !defined(NOREXX)
post_process_line(CURRENT_VIEW->focus_line);
rc = execute_macro_file(macroname,word[1]);
if (rc != RC_OK)
{
display_error(54,(char *)"");
rc = RC_SYSTEM_ERROR;
}
#else
/*---------------------------------------------------------------------*/
/* ...otherwise, process the file as a non-REXX macro file... */
/*---------------------------------------------------------------------*/
if ((fp = fopen(macroname,"r")) == NULL)
{
#ifdef TRACE
trace_return();
#endif
in_macro = FALSE;
free(macroname);
return(RC_ACCESS_DENIED);
}
post_process_line(CURRENT_VIEW->focus_line);
rc = execute_command_file(fp);
fclose(fp);
free(macroname);
#endif
/*---------------------------------------------------------------------*/
/* Set in_macro = FALSE to indicate we are out of the macro and do a */
/* show_page() now as long as there are still file(s) in the ring. */
/*---------------------------------------------------------------------*/
in_macro = FALSE;
if (number_of_files > 0)
show_page();
#ifdef TRACE
trace_return();
#endif
return(rc);
}